/*
 * Copyright (c) 2006, 2021, webrx.cn All rights reserved.
 *
 */
package cn.webrx;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题，也就是说volatile不能替代synchronized
 * 运行下面的程序，并分析结果
 * 程序的原子性指：整个程序中的所有操作，要么全部完成，要么全部不完成，不可能停滞在中间某个环节。
 * 原子性在一个操作是不可中断的，要么全部执行成功要么全部执行失败，有着“同生共死”的感觉。及时在多个线程一起执行的时候，一个操作一旦开始，就不会被其他线程所干扰。
 *
 * @author webrx [webrx@126.com]
 * @version 1.0
 * @since 17
 */
public class VolatileDemo {
    AtomicInteger count = new AtomicInteger(0);

    void m() {
        for (int i = 0; i < 100000; i++) {
            //相当于++
            count.incrementAndGet();

        }
    }

    public static void main(String[] args) {
        var t = new VolatileDemo();

        List<Thread> threads = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(t::m, "thread-" + i));
        }

        threads.forEach(Thread::start);

        threads.forEach((o) -> {
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        /*
        在很多情况下，主线程创建并启动子线程，如果子线程中要进行大量的耗时运算，主线程将早于子线程结束。这时，如果主线程想等子线程执行完成才结束，比如子线程处理一个数据，主线程想要获得这个数据中的值，就要用到join()方法了。方法join()的作用是等待线程对象销毁。

　　join方法的主要作用就是同步，它可以使得线程之间的并行执行变为串行执行。在A线程中调用了B线程的join()方法时，表示只有当B线程执行完毕时，A线程才能继续执行。

　　join方法中如果传入参数，则表示这样的意思：如果A线程中掉用B线程的join(10)，则表示A线程会等待B线程执行10毫秒，10毫秒过后，A、B线程并行执行。需要注意的是，jdk规定，join(0)的意思不是A线程等待B线程0秒，而是A线程等待B线程无限时间，直到B线程执行完毕，即join(0)等价于join()。(其实join()中调用的是join(0))

　　join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解：如果一个线程都没有start，那它也就无法同步了。
         */

        System.out.println(t.count.get());


    }
}
